const express = require('express')
const sqlQuery = require('../sql')
const router = express.Router()
const fs = require('fs')
const path = require('path')
const multer = require('multer')

// ================ 3001 路由接口
// 获取已有用户列表
async function handleGetUserList(req, res) {
  const strSql = `select * from chat_user where isgroup!=1 `
  const result = await sqlQuery(strSql)
  res.json(result)
}
// 注册用户
async function handleRegister(req, res) {
  const { username, password } = req.body
  try {
    const strSql =
      'insert into chat_user (username,password,avatarurl,isonline,isgroup) values (?,?,?,?,?)'
    const result = await sqlQuery(strSql, [
      username,
      password,
      '/public/images/user1.jpg',
      0,
      0,
    ])
    res.json({
      code: 0,
      msg: '注册成功',
    })
    console.log(result)
  } catch (error) {
    res.json({
      code: 0,
      msg: '注册失败',
    })
    console.log(error)
  }
}
// 上传图片文件
function handleUploadImg(req, res, next) {
  if (req.file.length === 0) {
    //判断一下文件是否存在，也可以在前端代码中进行判断。
    res.render('error', { message: '上传文件不能为空！' })
    return
  } else {
    let file = req.file
    console.log(file)
    let fileInfo = {}
    fs.renameSync(
      './public/upload/' + file.filename,
      './public/upload/' + file.originalname
    )
    //这里修改文件名字，比较随意。
    // 获取文件信息
    fileInfo.mimetype = file.mimetype
    fileInfo.originalname = file.originalname
    fileInfo.size = file.size
    fileInfo.path = path.join('/public/upload/', file.originalname)
    // 设置响应类型及编码
    res.json({
      code: 200,
      msg: '上传文件成功',
      data: fileInfo,
    })
  }
}
// 获取已有用户列表
router.get('/userlist', handleGetUserList)
// 注册用户
router.post('/user', handleRegister)

// 上传文件
router.post(
  '/upload',
  multer({
    //设置文件存储路径
    dest: 'public/upload', //upload文件如果不存在则会自己创建一个。
  }).single('singlefile'),
  handleUploadImg
)

//  ================socket 接口函数

//  登录事件处理函数
async function handleLoginEvent(data, socketCase) {
  // 判断用户名密码是否正确
  const { username, password } = data
  let strSql1 = `select * from chat_user where username='${username}' and password='${password}' `
  const result1 = await sqlQuery(strSql1)

  if (result1.length === 0) {
    socketCase.emit('login', {
      state: 'error',
      content: '用户名或密码错误',
    })
    return
  }

  if (result1[0].isonline === 1) {
    console.log('------preResult----')
    // 定向 socketid 发送消息
    socketCase.to(result1[0].socketid).emit('logout', {
      content: '你的账户在其他设备上登录',
    })
  }

  // 修改用户登录状态(socketid,isonline)
  let strSql2 = `update chat_user set socketid='${socketCase.id}',
  isonline=1
  where username='${username}'
  `
  const result2 = await sqlQuery(strSql2)
  socketCase.emit('loginToWeb', {
    state: 'ok',
    loginUser: result1[0],
    content: '登录成功',
  })

  // 获取聊天所需消息，这里先将未读已读放一块
  socketCase.on('getReadedMsgToServe', async (data) => {
    const { loginuser, chatuser } = data
    // 获取已读取的消息
    const strSqlReaded = `select * from chat_msg  where  (fromuser='${chatuser.username}' and touser='${loginuser.username}' ) OR (fromuser='${loginuser.username}' and touser='${chatuser.username}' ) LIMIT 0,50`
    const resultReaded = await sqlQuery(strSqlReaded)
    socketCase.emit('getReadedMsgToWeb', resultReaded)
  })

  // 获取未读取的消息
  const strSqlUnRead = 'select * from chat_msg where isread=? and touser=?'
  const resultUnRead = await sqlQuery(strSqlUnRead, [0, data.username])

  console.log(resultUnRead)
  // 触发未读信息接口事件，发送数据
  socketCase.emit('unReadMsg', Array.from(resultUnRead))

  // 加入群（房间）
  // 获取所有的群
  // const sqlStrGroup = 'select * from chat_user where isgroup=1'
  // const resultGroup = await sqlQuery(sqlStrGroup)
  // Array.from(resultGroup).forEach((item) => {
  //   socket.join(item.socketid)
  // })
}

// ===============未读事件函数
async function handleReadUnRead(data, socketCase) {
  // 将获取到的信息状态置为1 表示已读
  const strSqlSetRead = `update chat_msg set isread=1
 where touser='${data.username}'`
  const resultSetRead = await sqlQuery(strSqlSetRead)
}

// ==================离线事件函数
async function handleDisconnect(data, socketCase) {
  // 修改数据库登录信息(socketid,isonline)
  const strSql = `update chat_user set isonline=0
                        where socketid='${socketCase.id}'`
  const result = await sqlQuery(strSql)
}

// 发送信息事件函数
async function handleSendMsg(msg, socketCase) {
  // 判断收消息的人是否在线
  const strSql = 'select * from chat_user where username=? and isonline=?'
  const result = await sqlQuery(strSql, [msg.to.username, 1])

  if (result.length > 0) {
    // 如果此人在线，直接发消息
    const toid = result[0].socketid
    socketCase.to(toid).emit('directAcceptMsg', msg)
    // 将聊天内容存放到数据库，信息状态 1 已读
    const strSql2 =
      'insert into chat_msg (fromuser,touser,content,time,isread,type) values (?,?,?,?,?,?)'
    arr2 = [
      msg.from.username,
      msg.to.username,
      msg.content,
      msg.time,
      1,
      msg.type,
    ]

    const result2 = await sqlQuery(strSql2, arr2)
    // console.log(result2)
  } else {
    // 不在线，直接到数据库
    // 将聊天内容存放到数据库，信息状态 0 未读
    const strSql3 =
      'insert into chat_msg (fromuser,touser,content,time,isread,type) values (?,?,?,?,?,?)'
    arr3 = [
      msg.from.username,
      msg.to.username,
      msg.content,
      msg.time,
      0,
      msg.type,
    ]

    const result3 = await sqlQuery(strSql3, arr3)
  }
}

// 初始化 socket
function sockApiInit(app) {
  const serve = require('http').Server(app)

  // 给socket设置服务器监听 3002 端口
  serve.listen(3002)

  const io = require('socket.io')(serve)

  io.on('connection', function (socket) {
    socket.emit('connection', { msg: socket.id + '已分配连接id' })

    // 接收登录事件，修改数据库用户状态
    socket.on('loginToServer', (data) => {
      handleLoginEvent(data, socket)
    })

    // 监听 用户查看未读消息事件
    socket.on('readUnRead', (data) => {
      handleReadUnRead(data, socket)
    })

    // 监听 关闭客户端时的事件
    socket.on('disconnect', (data) => {
      handleDisconnect(data, socket)
    })

    // 监听发送过来的数据
    socket.on('sendMsg', (data) => {
      handleSendMsg(data, socket)
    })
  })
}

module.exports = {
  router,
  sockApiInit,
}
